package plutuscat.shishicai.common;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import plutuscat.shishicai.domain.Lottery;
import plutuscat.shishicai.util.RarDecompressionUtil;

/**
* http://data.shishicai.cn/cqssc/haoma/ 重庆时时彩站点下载的彩票历史数据
* @author dw_chenqi
* @date 2016年5月6日下午2:09:27
*/
@Component
public class DefaultHistoryLotteryDataProvider implements HistoryLotteryDataProvider {
	private static final Logger log = LoggerFactory.getLogger(DefaultHistoryLotteryDataProvider.class);

	private static final String downloadFileName = "history.rar";
	// 下载文件的解压密码
	private static final String FILE_DECOMPRESS_PWD = "www.shishicai.cn";

	//下载解压的文件是UTF BOM编码
	public static final String UTF8_BOM = "\uFEFF";

	@Value("${url.lottery.history}")
	protected String historyDataUrl;
	@Value("${disk.lottery.history}")
	protected String histroyDataDiskPath;

	@Override
	public Set<Lottery> provideDataWithLotteryTimeAsc() {
		BufferedReader br = null;
		Set<Lottery> set = new TreeSet<Lottery>(new Lottery.LotteryComparator());
		try {
			File historyDataFile = getHistoryDataFile();
			br = new BufferedReader(new InputStreamReader(new FileInputStream(historyDataFile)));
			String line = null;
			while ((line = br.readLine()) != null) {
				if (StringUtils.isNotBlank(line)) {
					if (line.startsWith(UTF8_BOM)) {
						line = removeUTFBom(line);
					}
					String[] parts = line.split("\t");
					Lottery lottery = new Lottery.Builder() //
							.lotteryTime(parts[0]) //
							.winNumbers(parts[1]) //
							.build();
					set.add(lottery);
				}
			}
			return set;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new RuntimeException(e);
		} finally {
			IOUtils.closeQuietly(br);
		}

	}

	private String removeUTFBom(String line) {
		return line.substring(1); // remove utf-8 bom
	}

	private File getHistoryDataFile() throws IOException {
		File downloadedFile = downloadHistoryDataFile();
		return decompressFile(downloadedFile);
	}

	/**
	 * 解压文件
	 * @param srcRarFile
	 * @return
	 */
	private File decompressFile(File srcRarFile) {
		try {
			RarDecompressionUtil.unrar(srcRarFile, srcRarFile.getParent(), FILE_DECOMPRESS_PWD);
		} catch (IOException e) {
			throw new RuntimeException("下载的彩票数据解压过程出错!");
		}
		File[] files = srcRarFile.getParentFile().listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith(".txt");//解压出来的txt文件
			}
		});
		return files[0];
	}

	/**
	 * 下载文件
	 * @return
	 * @throws IOException
	 */
	private File downloadHistoryDataFile() {
		if (StringUtils.isBlank(historyDataUrl)) {
			throw new IllegalArgumentException("url.lottery.history为空,可能是没有配置彩票历史数据下载url!");
		}
		InputStream in = null;
		OutputStream out = null;
		try {
			HttpGet get = new HttpGet(historyDataUrl);
			HttpEntity resEntity = HttpClients.createDefault().execute(get).getEntity();
			if (resEntity != null) {
				in = resEntity.getContent();
				File srcRarFile = new File(createCleanDirectory(), downloadFileName);
				out = new FileOutputStream(srcRarFile);
				IOUtils.copy(in, out);
				return srcRarFile;
			}
			return null;
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			IOUtils.closeQuietly(out);
			IOUtils.closeQuietly(in);
		}

	}

	private File createCleanDirectory() {
		if (StringUtils.isBlank(histroyDataDiskPath)) {
			throw new IllegalArgumentException("未配置彩票数据的保存目录,可能是配置文件中缺失disk.lottery.history!");
		}
		File dir = new File(histroyDataDiskPath);
		//目录不存在就创建,存在就删除以前的数据
		if (!dir.exists()) {
			dir.mkdirs();
		} else {
			for (File f : dir.listFiles()) {
				f.delete();
			}
		}
		return dir;
	}

}
